const Koa = require('koa');
const app = new Koa();
const views = require('koa-views');
const json = require('koa-json');
const onerror = require('koa-onerror');
const bodyparser = require('koa-bodyparser');
const logger = require('koa-logger');
const jwt = require('koa-jwt');
const fs = require('fs');
const { PATH_WHITE_LIST } = require('./constant/routes');
const { PUBLIC_KEY_PATH, ALGORITHMS } = require('./constant/jwt');
const refreshToken = require('./middlewares/refresh-token');
const cors = require('./middlewares/cors');
const { isRevoked } = require('./helpers/jwt');

const swagger = require('./swagger');
const users = require('./routes/user');
const goods = require('./routes/goods');

// 引入redis
const redis = require('./helpers/redis');
app.context.redis = redis;

// error handler
onerror(app);

// JWT设置
// 加密公钥
const publicKey = fs.readFileSync(PUBLIC_KEY_PATH);
app.use(
    jwt({
        debug: process.env.DEBUG,
        secret: publicKey,
        algorithms: ALGORITHMS,
        isRevoked
    }).unless({
        path: PATH_WHITE_LIST
    })
);
// 自动刷新JWT
app.use(
    refreshToken({
        debug: process.env.DEBUG
    }).unless({
        path: PATH_WHITE_LIST
    })
);

// middlewares
app.use(
    bodyparser({
        enableTypes: ['json', 'form', 'text']
    })
);
app.use(json());
app.use(logger());
app.use(cors());
app.use(require('koa-static')(__dirname + '/public'));

app.use(
    views(__dirname + '/views', {
        extension: 'pug'
    })
);

// logger
app.use(async (ctx, next) => {
    const start = new Date();
    await next();
    const ms = new Date() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

// routes
app.use(swagger.routes());
app.use(users.routes(), users.allowedMethods());
app.use(goods.routes(), goods.allowedMethods());

// error-handling
app.on('error', (err, ctx) => {
    console.error('server error', err, ctx);
});

module.exports = app;
